#include "insertValue.h"
#define FILE_TYPE_FILE 0
#define FILE_TYPE_DIR  1
//fileType=0表示文件，fileType=1表示目录
static pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
MYSQL *mysql=NULL;
int mysqlConnect(){
    //上锁
    pthread_mutex_lock(&mutex);
    
    mysql=mysql_init(NULL);
    
    MYSQL *ret=mysql_real_connect(mysql,"localhost","root","123","zqy",0,NULL,0);
    MYSQL_CONNECT_CHECK(ret==NULL,mysql,"connect failed");
    
    pthread_mutex_unlock(&mutex);
    return 0;
}
int insertValue(MYSQL *mysql,metadata_t *meta){
    char query[4096];
    int ret;

    snprintf(query, sizeof(query), 
             "INSERT INTO vfs (fileName, userName, parentId, fileType, path,hashValue, isDeleted,refCount) "
             "VALUES ('%s', '%s', %d, %d, '%s','%s', %d, %d)",
             meta->fileName, meta->userName, meta->parentId, meta->fileType, meta->path,meta->hashValue,meta->isDeleted,meta->refCount);
    ret =mysql_real_query(mysql,query,strlen(query));
    
    if(ret !=0){
        fprintf(stderr,"Insert error:%s\n",mysql_error(mysql));
        return -1;
    }
    printf("Insert successful!\n");
    return 0;
}

//初始化一个parentPath存目录路径也就是父路径，char parentPath[100];
int getParentPath(MYSQL *mysql,int parentId,char *parentPath){
    //如果不存在父id
    if(parentId==-1){
        strcpy(parentPath,"/");
        return 0;
    }
    
    char query[1024];
    snprintf(query, sizeof(query), 
             "SELECT path FROM vfs WHERE id = %d AND fileType = %d", 
             parentId, FILE_TYPE_DIR);
    int ret =mysql_real_query(mysql,query,strlen(query));
    if(ret!=0){
        fprintf(stderr,"getParentPath query error:%s\n",mysql_error(mysql));
        return -1;
    }
    MYSQL_RES *result = mysql_store_result(mysql);
    if(result==NULL){
        printf("result error:%s\n",mysql_error(mysql));
        return -2;
    }
    MYSQL_ROW row=mysql_fetch_row(result);
    if(row==NULL){
        printf("fetch row error:%s\n",mysql_error(mysql));
        return -3;
    }
    strcpy(parentPath,row[0]);
    mysql_free_result(result);
    return 0;
}


//将获得的目录路径与filename拼接得到真正路径
//初始化char path[100]用来存;
int  buildFullPath(MYSQL *mysql, int parentId, const char *fileName, char *fullPath){
    char parent[1024];
    //获取父路径
    getParentPath(mysql,parentId,parent);
    //拼接获得绝对路径
    if (strcmp(parent, "/") == 0) {
        sprintf(fullPath, "/%s", fileName);
    } else {
        sprintf(fullPath, "%s/%s", parent, fileName);
    }
    return 0;
}
//初始化根目录并插入（只跑一次）
int initUserRoot(MYSQL *mysql, const char *userName){
    int rootId=getFileIdByPath(mysql,userName,"/",FILE_TYPE_DIR);
    if(rootId!=-1){
        return rootId;
    }
    //返回根目录id
    metadata_t root;
    bzero(&root,sizeof(root));
    strcpy(root.fileName,"/");
    strcpy(root.hashValue,"NULL");
    strcpy(root.path,"/");
    strcpy(root.userName,userName);
    root.fileType=FILE_TYPE_DIR;
    root.isDeleted=0;
    root.parentId=-1;
    root.refCount=0;
    //插入数据库
    int ret=insertValue(mysql,&root);
    if(ret==0){
        return mysql_insert_id(mysql);
    }
    return -1;
}
//根据绝对路径查id
int  getFileIdByPath(MYSQL *mysql, const char *userName, const char *path, int type){
    
    char query[1024];
    snprintf(query, sizeof(query), 
             "SELECT id FROM vfs WHERE userName='%s' AND path = '%s' AND fileType = %d", 
             userName,path, type);
    int ret =mysql_real_query(mysql,query,strlen(query));
    if(ret!=0){
        fprintf(stderr,"getParentPath query error:%s\n",mysql_error(mysql));
        return -1;
    }
    MYSQL_RES *res = mysql_store_result(mysql);
    MYSQL_ROW row = mysql_fetch_row(res);
    int id = row ? atoi(row[0]) : -1;
    mysql_free_result(res);
    return id;
}
int main(int argc,char *argv[]){
        //连接数据库
        mysqlConnect();
        //1 . 初始化
        //验证密码登陆成功一个账户就插入初始化一个/（文件名）插入进去，显示登陆成功后，将接收的client.userName插入
        //parentId初始化为-1, fileType默认为0, path为/,hashValue为NULL, isDeleted为0，refCount为0。
        client_t client;
        strcpy(client.userName,"wanggang");
        client.currentDirId=initUserRoot(mysql,client.userName);
        
        // 2. 模拟mkdir，需要插入的操作
        //mkdir需要封装函数我这里直接定义了
        metadata_t metaDir;
        bzero(&metaDir,sizeof(metaDir));
        //插入时候只需要获得parentId,filename,
        strcpy(metaDir.userName,client.userName);
        strcpy(metaDir.fileName,"dir1");
        //由文件名和目录拼接绝对路径
        strcpy(metaDir.hashValue,"NULL");
        metaDir.fileType=FILE_TYPE_DIR;
        metaDir.isDeleted=0;
        metaDir.parentId=client.currentDirId;
        metaDir.refCount=0;
        buildFullPath(mysql,metaDir.parentId,metaDir.fileName,metaDir.path);
        //上传数据库
        insertValue(mysql,&metaDir);

        // 3. 模拟上传文件时，需要插入的操作
        // 已经完成上传到实际文件目录下时，增加的操作
        
        metadata_t metaFile;
        bzero(&metaFile,sizeof(metaFile));
        //插入时候只需要获得parentId,filename,
        strcpy(metaFile.userName,client.userName);
        strcpy(metaFile.fileName,"file1");
        strcpy(metaFile.hashValue,"$6$nawodnaodaiwhdndw$");
        metaFile.fileType=FILE_TYPE_FILE;
        metaFile.isDeleted=0;
        metaFile.parentId=client.currentDirId;
        metaFile.refCount=1;
        //由文件名和目录拼接绝对路径
        buildFullPath(mysql,metaFile.parentId,metaFile.fileName,metaFile.path);
        //上传数据库
        insertValue(mysql,&metaFile);


        //关闭数据库
        mysql_close(mysql);
        printf("mysql connect close\n");
        return 0;

}

